<template>
  <div>
    <el-collapse-item name="execution">
      <template #title>
        <el-icon>
          <BellFilled />
        </el-icon>执行监听器
      </template>
      <el-table class="ListenerList" :data="newExeListenenrList" style="width: 100%">
        <el-table-column label="事件类型">
          <template #default="scope">
            {{ scope.row.event === 'take' ? '启用' : scope.row.event === 'start' ? '开始' : '结束' }}
          </template>
        </el-table-column>
        <el-table-column label="监听器类型">
          <template #default="scope">
            {{ scope.row.type === 'class' ? '类' : scope.row.type === 'expression' ? '表达式' : scope.row.type ===
              'delegateExpression' ? '代理表达式' : '脚本' }}
          </template>
        </el-table-column>
        <el-table-column prop="prop" label="操作">
          <template #default="scope">
            <el-button type="danger" @click="delListener(scope)">
              <el-icon>
                <Delete />
              </el-icon>
            </el-button>
            <el-button type="primary" @click="editListener(scope)">
              <el-icon>
                <Edit />
              </el-icon>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button type="primary" style="width: 100%;" @click="addExeListener">
        <el-icon>
          <Plus />
        </el-icon>
        添加监听器</el-button>
      <el-form v-if="isEditListener" class="listenerform" label-width="auto" style="margin-top: 20px;">
        <el-text type="danger">注意：一次只允许添加一条监听器</el-text>
        <el-form-item label="事件类型" required>
          <el-radio-group v-model="executionListener.event" size="default" style="width: 300px;">
            <el-radio-button label="开始" value="start"></el-radio-button>
            <el-radio-button label="结束" value="end"></el-radio-button>
            <el-radio-button label="启用" value="take"></el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item>
          <el-radio-group v-model="executionListener.type">
            <el-radio label="Java类" value="class"></el-radio>
            <el-radio label="表达式" value="expression"></el-radio>
            <el-radio label="代理表达式" value="delegateExpression"></el-radio>
          </el-radio-group>
          <el-input v-model="executionListener[executionListener.type]" placeholder="监听器表达式"
            style="width: calc(100% - 100px);"></el-input>
          <el-link style="color:white;width: 90px; background-color: var(--el-color-primary);">
            <el-icon>
              <Search />
            </el-icon>
            内置
          </el-link>
          <el-divider border-style="dashed"></el-divider>
          <div class="field">
            <el-text tag="b">注入字段</el-text>
            <el-button type="primary" size="small" @click="addFieldparams">创建字段</el-button>
          </div>
          <el-table class="customField" :data="executionListener.fields" style="width: 100%">
            <el-table-column prop="name" label="字段名" align="center">
            </el-table-column>
            <el-table-column label="字段类型" align="center">
              <template #default="scope">
                {{ scope.row.$type === 'stringValue' ? '字符串' : '表达式' }}
              </template>
            </el-table-column>
            <el-table-column prop="value" label="字段值" align="center">
            </el-table-column>
            <el-table-column prop="prop" label="操作" align="center" width="100px">
              <template #default="scope">
                <div style="display: auto;">
                  <el-button type="danger" @click="delCustomField(scope)">
                    <el-icon>
                      <Delete />
                    </el-icon>
                  </el-button>
                  <el-button type="primary" @click="editCustomField(scope)">
                    <el-icon>
                      <Edit />
                    </el-icon>
                  </el-button>
                </div>

              </template>
            </el-table-column>
          </el-table>
          <!-- </el-tab-pane>
        </el-tabs> -->
        </el-form-item>
        <el-form-item class="button">
          <el-button type="default" @click="isEditListener = false">关闭</el-button>
          <el-button type="primary" @click="updateListener">确认</el-button>
        </el-form-item>
      </el-form>
    </el-collapse-item>
    <!-- 新增字段 -->
    <el-drawer title="注入字段" v-model="isfieldparams" :before-close="handleClose" size="400">
      <el-form ref="form" :model="fieldparam" label-width="auto">
        <el-form-item label="字段名称" required>
          <el-input v-model="fieldparam.name" placeholder=""></el-input>
        </el-form-item>
        <el-form-item label="字段类型" required>
          <el-radio-group v-model="fieldparam.$type">
            <el-radio-button label="字符串" value="stringValue"></el-radio-button>
            <el-radio-button label="表达式" value="expression"></el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="字段值" required="">
          <el-input v-model="fieldparam.value" placeholder=""></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="closeDrawer">取消</el-button>
          <el-button type="primary" @click="fieldParamConfirm">确认</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
const element = defineModel("element", {
  default: {
    id: '',
    name: '',
    type: ''
  }
})
const props = defineProps({
  bpmnModeler: Object
})

const isEditListener = ref(false)
const newExeListenenrList = ref([])
function init() {
  // console.log('执行监听器init执行')
  if (element.value.extensionElements?.values?.length) {
    let exeElements = element.value.extensionElements.values.filter(item => item.$type === 'flowable:ExecutionListener')
    exeElements.forEach(item => {
      let typeCNlist = Object.getOwnPropertyNames(item)
      if (typeCNlist.includes('expression')) {
        // item.typeCN = '表达式'
        item.type = 'expression'
      }
      if (typeCNlist.includes('class')) {
        // item.typeCN = 'Java类'
        item.type = 'class'
      }
      if (typeCNlist.includes('delegateExpression')) {
        // item.typeCN = '代理表达式'
        item.type = 'delegateExpression'
      }
    })
    newExeListenenrList.value = JSON.parse(JSON.stringify(exeElements))
    if (newExeListenenrList.value?.fields) {
      newExeListenenrList.value.forEach(item => {
        item.fields = item.fields.map(item => {
          let field = {
            name: '',
            $type: '',
            value: '',
          }
          field.name = item.name
          field.$type = item.expression ? 'expression' : 'stringValue'
          field.value = item[field.$type]
          // console.log(item, 'field', field)
          return field
        })
      })
    }
  } else {
    newExeListenenrList.value = []
  }
}
init()
watch(element, () => {
  init()
  // console.log('监听器element变化', element.value.id, newExeListenenrList.value)
}, { deep: true }
)

const executionListener = ref({
  $type: 'flowable:ExecutionListener',
  event: '',
  type: '',
  fields: []
})

// 编辑监听器
function delListener(scope) {
  console.log(scope.$index)
  newExeListenenrList.value = newExeListenenrList.value.filter(item => newExeListenenrList.value.indexOf(item) !== scope.$index)
  updateElement()
}
const editListNum = ref()
function editListener(scope) {
  console.log(scope.$index)
  editListNum.value = scope.$index
  executionListener.value = newExeListenenrList.value.at(scope.$index)
  isEditListener.value = true
}
// 新增监听器
const isAddListener = ref(false)
function addExeListener() {
  executionListener.value = {
    $type: 'flowable:ExecutionListener',
    event: '',
    type: '',
    fields: []
  }
  isAddListener.value = true
  isEditListener.value = true
}
function updateListener() {
  if (isAddListener.value) {
    newExeListenenrList.value.push(executionListener.value)
    executionListener.value = {
      $type: 'flowable:ExecutionListener',
      event: '',
      type: '',
      fields: []
    }
  }
  // 将newnewExeListenenrList值传入modeler
  updateElement()
  isEditListener.value = false
  isAddListener.value = false

}
// 注入字段表格
const isAdd = ref(true)
const editIndex = ref()
function delCustomField(data) {
  console.log(data.$index)
  executionListener.value.fields = executionListener.value.fields.filter(item => executionListener.value.fields.indexOf(item) !== data.$index)
}
function editCustomField(scope) {
  console.log(scope.row)
  isAdd.value = false
  editIndex.value = scope.$index
  fieldparam.value = scope.row
  isfieldparams.value = true
}
// 注入字段
const isfieldparams = ref(false)
const fieldparam = ref({
  name: '',
  $type: '',
  value: '',
})
function addFieldparams() {
  isAdd.value = true
  fieldparam.value = {}
  isfieldparams.value = true

}
function handleClose(done) {
  ElMessageBox.confirm('确定关闭吗')
    .then(() => {
      done()
    })
}
function closeDrawer() {
  isfieldparams.value = false
  fieldparam.value = {}
}
function fieldParamConfirm() {
  if (isAdd.value) {
    executionListener.value.fields.push(fieldparam.value)
    isfieldparams.value = false
  } else {
    executionListener.value.fields.splice(editIndex.value, 1, fieldparam.value)
    isfieldparams.value = false
  }
}
function updateElement() {
  // 生成xml结构及内容，后续整体加载到element上
  const modeling = props.bpmnModeler.get("modeling")
  const moddle = props.bpmnModeler.get("moddle")
  console.log(modeling)
  console.log(props.bpmnModeler)
  if (newExeListenenrList?.value.length) {
    //获取当前element下的extensionElements
    let extensionElements = element.value.get('extensionElements')
    // 如果没有extensionElements，就创建
    if (!extensionElements) {
      extensionElements = moddle.create('bpmn:ExtensionElements')
    }
    //清除旧值
    if (extensionElements?.values) {
      extensionElements.values = extensionElements.values.forEach(item => item.$type !== 'flowable:ExecutionListener') ?? []
    }
    newExeListenenrList.value.forEach(item => {
      let executionListenerTemplate = moddle.create('flowable:ExecutionListener')
      executionListenerTemplate['event'] = item.event
      executionListenerTemplate[item.type] = item[item.type]
      if (item.fields && item.fields.length) {
        item.fields.forEach(field => {
          let fieldElementTemplate = moddle.create('flowable:Field')
          fieldElementTemplate['name'] = field.name
          fieldElementTemplate[field.$type] = field.value
          executionListenerTemplate.get('fields').push(fieldElementTemplate)
        })
      }
      extensionElements.get('values').push(executionListenerTemplate)
    })
    const editElement = props.bpmnModeler.get("elementRegistry").get(element.value.id)
    modeling.updateProperties(editElement, { extensionElements: extensionElements })
  } else {
    let extensionElements = element.value.get('extensionElements')
    if (extensionElements) {
      extensionElements.values = extensionElements.values?.filter(item => item.$type !== 'flowable:ExecutionListener') ?? []
    }
  }

}

</script>

<style lang="less" scoped>
.ListenerList {
  .el-button {
    width: 30px;
  }
}

:deep(.el-collapse-item__header) {
  font-weight: 700;
  background-color: var(--el-color-primary-light-9);
  border-radius: 10px;
}

.el-icon {
  margin: 0 10px;
}

.button {
  :deep(.el-form-item__content) {
    justify-content: flex-end;
  }
}

.listenerform {
  border: 1px solid var(--el-color-primary-light-7);
  background-color: var(--el-color-primary-light-9);
  border-radius: 5px;
  padding: 5px;
}

.field {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.customField {
  .el-button {
    width: 30px;
  }

  :deep(th.el-table__cell.is-leaf) {
    background-color: var(--el-color-primary-light-7);
  }
}
</style>